/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * CopyFrame.java
 *
 * Created on May 30, 2009, 12:48:30 AM
 */

package net.sf.bluex.explorer.boundary;

import net.sf.bluex.components.SeletionDetail;
import net.sf.bluex.components.Stack;
import net.sf.bluex.components.StackSizeComputer;
import java.io.File;
import java.util.Vector;
import javax.swing.JOptionPane;
import net.sf.bluex.boundary.BaseWindow;
import net.sf.bluex.components.BlueXStatics;
import net.sf.bluex.controller.BaseWindowManagement;
import net.sf.bluex.controller.FileModule;
import net.sf.bluex.controller.FolderIntruder;
import net.sf.bluex.controller.UsefulMethods;
import net.sf.bluex.explorer.components.MyTableModel;
import net.sf.bluex.threads.UninterruptableThread;

/**
 *
 * @author Blue
 */
public class DeleteFrame extends javax.swing.JFrame implements Runnable{

    //thread related objects
    private boolean active=false, paused=false;
    public UninterruptableThread t;

    /** stack to store the source files */
    private Stack<File> stSourceFiles;

    //long variable to hold the total size
    private static int PROGRESS_BAR_MAX=Integer.MAX_VALUE/8;
    private double clusterSize;

    //make a variable to count the copyied files
    private int copyFileCount=0;

    //for the details of the all source files
    private SeletionDetail sd;

    //the StackSizeComputer thread
    private StackSizeComputer ssc=new StackSizeComputer();

    //basewindow object
    private BaseWindow bw;
    
    /**
     * This constructor creates a copy frame object, it takes a stack of files and the destination folder location as input
     * @param stSourceFiles
     * @param destFile
     */
    public DeleteFrame(Stack<File> stSourceFiles, BaseWindow bw) {
        super("Deleting...");
        this.bw=bw;
        initComponents();

        //save a copy of stack in the local object
        this.stSourceFiles=stSourceFiles.getReverseCopy();

        //change the background
        //set the color of the panel
        taCurrentFolder.setBackground(this.jPanel2.getBackground());
        
        //jtable inits
        jTable.setShowVerticalLines(false);
        jTable.setShowHorizontalLines(false);
        //call the function to fill the table with the contents from the global copy stack
        fillTable();

        //frame init
        this.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        this.addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent we){
                doCancelJob();
            }
        });

        cmdStart.requestFocus();
        this.setIconImage(UsefulMethods.getImage(FileModule.APP_ICON));
        this.setLocationByPlatform(true);
        this.setVisible(true);
    }

    private void deleteFile(File currentFile) {
        currentFile.delete();

        //increment the filecount
        lbDeletedFileCount.setText((++copyFileCount)+"/"+sd.getFilesCount());

        //increment the bar
        incrementProgressBar();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel2 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        txtCurrentFile = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        jsp1 = new javax.swing.JScrollPane();
        taCurrentFolder = new javax.swing.JTextArea();
        jsprogCopy = new javax.swing.JProgressBar();
        jPanel1 = new javax.swing.JPanel();
        cmdRemove = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        lbTotalCount = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        lbDeletedFileCount = new javax.swing.JLabel();
        cmdStart = new javax.swing.JButton();
        cmdCancel = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Current File Details:"));

        jLabel4.setText("File Name:");

        txtCurrentFile.setEditable(false);
        txtCurrentFile.setBorder(null);

        jLabel5.setText("Current Folder:");

        jsp1.setBorder(null);

        taCurrentFolder.setBackground(new java.awt.Color(236, 233, 216));
        taCurrentFolder.setColumns(20);
        taCurrentFolder.setEditable(false);
        taCurrentFolder.setFont(new java.awt.Font("Tahoma", 0, 11));
        taCurrentFolder.setLineWrap(true);
        taCurrentFolder.setRows(4);
        jsp1.setViewportView(taCurrentFolder);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jsp1, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
                    .addComponent(txtCurrentFile, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(txtCurrentFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addComponent(jsp1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        jsprogCopy.setString("Click Start to Delete");
        jsprogCopy.setStringPainted(true);

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Added Files/Folders:"));

        cmdRemove.setText("Restore");
        cmdRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdRemoveActionPerformed(evt);
            }
        });

        jTable.setModel(new net.sf.bluex.explorer.components.MyTableModel());
        jScrollPane1.setViewportView(jTable);

        jLabel1.setText("Total Files/Folders:");

        lbTotalCount.setFont(new java.awt.Font("Tahoma", 1, 11));
        lbTotalCount.setText("Count");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 472, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lbTotalCount)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 271, Short.MAX_VALUE)
                        .addComponent(cmdRemove)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 106, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmdRemove)
                    .addComponent(jLabel1)
                    .addComponent(lbTotalCount)))
        );

        jLabel6.setText("Files Copied:");

        lbDeletedFileCount.setText("0/0");

        cmdStart.setFont(new java.awt.Font("Tahoma", 1, 11));
        cmdStart.setText("Start");
        cmdStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdStartActionPerformed(evt);
            }
        });

        cmdCancel.setText("Cancel");
        cmdCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdCancelActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jsprogCopy, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 508, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jLabel6)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lbDeletedFileCount)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 293, Short.MAX_VALUE)
                        .addComponent(cmdStart)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cmdCancel)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jsprogCopy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(lbDeletedFileCount)
                    .addComponent(cmdCancel)
                    .addComponent(cmdStart))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cmdRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRemoveActionPerformed
        // TODO add your handling code here:
        doRemoveSourceJob();
}//GEN-LAST:event_cmdRemoveActionPerformed

    private void cmdCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdCancelActionPerformed
        // TODO add your handling code here:
        doCancelJob();
    }//GEN-LAST:event_cmdCancelActionPerformed

    private void cmdStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdStartActionPerformed
        // TODO add your handling code here:
        doStartJob();
    }//GEN-LAST:event_cmdStartActionPerformed

    private void doRemoveSourceJob() {
        if(jTable.getSelectedRow()!=-1){
            int[] rows=jTable.getSelectedRows();
            
            for(int i : rows){
                int index=jTable.getRowCount()-i-1;
                stSourceFiles.removeItem(index);
                fillTable();
            }
        }else
            JOptionPane.showMessageDialog(this, "You have not selected any file.\n" +
                    "Please select any first.", "Error", JOptionPane.ERROR_MESSAGE);
    }

    public void run(){
        //make a copy of all stack items
        Stack<File> stCopy=stSourceFiles.getAnotherCopy();//so that updations can be made after the copying process

        //start the copy yaar
        active=true;
        paused=false;

        //disable start button
        cmdStart.setEnabled(false);

        //get the folder size
        getFolderSize();

        //enable start button
        cmdStart.setEnabled(true);

        //set the label of files count
        lbDeletedFileCount.setText("0/"+sd.getFilesCount());

        File currentFile;
        while((currentFile=stSourceFiles.pop())!=null){
            if(currentFile.isDirectory()){
                doDeletionJob(currentFile);
            }
            else{//if file
                //set path text area
                taCurrentFolder.setText(currentFile.getParent());

                //set the filename text field
                txtCurrentFile.setText(currentFile.getName());

                //delete the file
                deleteFile(currentFile);
            }
        }

        if(bw!=null){
            //make updations to all bws
            File temp;
            int i=0;
            File[] files=new File[stCopy.size()];
            while((temp=stCopy.pop())!=null){
                if(!temp.exists())
                    files[i++]=temp;
            }

            bw.dataUpdated(files, BaseWindowManagement.DELETE);
        }

        //stop delete
        doCancelJob();
    }
    
    /**
     * private methods..
     */

    /**
     * method to get the size of each and every folder/file and total size.
     */
    private void getFolderSize(){
        //set indeterminate mode on
        jsprogCopy.setIndeterminate(true);

        //set the text in the progress bar as calculating the total space
        this.jsprogCopy.setString("Calculating total space...");

        //set folsize variable
        sd=new SeletionDetail();

        //get the individual sizes and add them to the sd object
        //reverse stack and then calculate
        Stack<File> revStack=stSourceFiles.getReverseCopy();
        for(int i=0; i<revStack.size(); i++){
            if(active){
                Stack tempStack=new Stack();
                tempStack.push(revStack.elementAt(i));

                SeletionDetail tempSD=ssc.getAllFolderLengthOfStack(tempStack);

                //set the sizes in the table
                jTable.setValueAt(UsefulMethods.getFileSize(tempSD.getTotalSize()), i, 4);

                //add to global sd object
                sd.addSelectionDetail(tempSD);
            }
        }

        //set the clusterSize variable
        clusterSize=(double)PROGRESS_BAR_MAX/(double)sd.getFilesCount();

        //set indeterminate mode off
        jsprogCopy.setIndeterminate(false);

        //set the max value of the progress bar
        jsprogCopy.setMaximum(PROGRESS_BAR_MAX);
    }

    /**
     * delete function for folders
     */
    private void doDeletionJob(File parentFile){
        Stack<File> stDeleteFolders=new Stack<File>();

        /////////////put the parentFile in the stack
        stDeleteFolders.push(parentFile);
        //////////////

        ///create a stack it will contains the info about the folders which are popped
        //when every file is deleted delete all folders using this array list
        Stack<File> stFolders=new Stack<File>();

        //do delete operation

        /////////////////////////////////////////////////////////////////////////delete all files
        File parentFolder=null;
        while((active && (parentFolder=stDeleteFolders.pop())!=null)){

            //add the folder in the arrFolder arraylist
            stFolders.push(parentFolder);

            //set path text area
            taCurrentFolder.setText(parentFolder.getAbsolutePath());

            //create a instance of files object which contains all files and folders for corresoponding parent folder
            File[] file=FolderIntruder.getFilesFolders(parentFolder);

            //if the file object is not null then go inside else outside return.
            if(file!=null){

                //do the job of iteration
                for(File tempFile : file){
                    if(active){//to stop the deleting operation inbetween
                        try{
                            //set the filename text field
                            txtCurrentFile.setText(tempFile.getName());
                            if(tempFile.isFile()){//ensures file
                                //delete the file
                                deleteFile(tempFile);
                            }
                            else if(tempFile.isDirectory()){
                                stDeleteFolders.push(tempFile);
                            }
                        }catch(NullPointerException npe){
                            //pass the exception
                        }
                    }

                    while(paused);//pausing the thread
                }
            }
            while(paused);//pausing the thread
        }
        ///////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////delete all folders
        File tempFolder;
        while((tempFolder=stFolders.pop())!=null){
            tempFolder.delete();
        }
        //////////////////////////////////
    }

    private void incrementProgressBar(){
        //set the progress bar value
        int fill=(int)(copyFileCount*clusterSize);
        jsprogCopy.setValue(fill);
        jsprogCopy.setString((int)((float)fill/(float)PROGRESS_BAR_MAX*100)+"%");
    }

    /**
     * it will do task of filling the table with the data
     * @return
     */
    private void fillTable(){
        //make vector of vector object to get the data to be displayed
        Vector<Vector> data=new Vector<Vector>();

        //make the data vector filled
        for(int i=stSourceFiles.size()-1;i>=0;i--)
            data.add(getTableRow((File)stSourceFiles.elementAt(i),stSourceFiles.size()-1-i));

        jTable.setModel(new MyTableModel(data, CopyFrame.getColumnHead()));

        //now resize the table
        resizeTable();

        //set the count variable
        this.lbTotalCount.setText(stSourceFiles.size()+"");
    }

    /**
     * resize the table
     */
    private void resizeTable(){
        for(int i=0;i<CopyFrame.getColumnHead().size();i++){

            //rezise
            int size=100;
            if(i==0)
                size=25;
            else if(i==1)
                size=130;
            else if(i==2)
                size=100;
            else if(i==3)
                size=70;
            else if(i==4)
                size=70;
            else if(i==5)
                size=50;

            jTable.getColumnModel().getColumn(i).setPreferredWidth(size);
        }
        jTable.getParent().setBackground(java.awt.Color.WHITE);
        jTable.setRowHeight(19);
        jTable.setAutoResizeMode(jTable.AUTO_RESIZE_OFF);
        jTable.requestFocus();
    }

    /**
     * this method takes a file object as an argument and returns the<b/>
     * vector object which contains the data related to the file
     * @param file
     * @return
     */
    private Vector<Object> getTableRow(File file, int i){
        //object array data which is returned through this method
        Vector<Object> data=new Vector<Object>();

        //set data
        //1. set icon
        data.add(BlueXStatics.getIcon(file));

        //2. set file name
        data.add(BlueXStatics.getFileName(file));

        //3. set location of file
        data.add(file.getParent());

        //4. type of the file. type description
        data.add(BlueXStatics.getFileDescription(file));

        //5. size of the files/dirs
        //set dirs to nothing and files to the actual size they have
        if(file.isDirectory())
            data.add("");//left empty
        else //for files
            data.add(UsefulMethods.getFileSize(file.length()));

        //6. status
        //set the all to empty and when anyone is completed then set it to "Done"
        data.add("");//empty

        //return the object
        return data;
    }

    public void doStartJob(){
        if(cmdStart.getText().equals("Start")){
            t=UninterruptableThread.getMyThread(this, "Deleting Thread");
            t.start();
            cmdStart.setText("Pause");
            cmdRemove.setEnabled(false);
        }else if(cmdStart.getText().equals("Pause")){
            this.paused=true;
            cmdStart.setText("Resume");
        }
        else{
            this.paused=false;
            cmdStart.setText("Pause");
        }
    }

    public UninterruptableThread getT() {
        return t;
    }

    public void doCancelJob(){
        paused=false;
        active=false;
        ssc.stop();
        this.dispose();
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cmdCancel;
    private javax.swing.JButton cmdRemove;
    private javax.swing.JButton cmdStart;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable;
    private javax.swing.JScrollPane jsp1;
    private javax.swing.JProgressBar jsprogCopy;
    private javax.swing.JLabel lbDeletedFileCount;
    private javax.swing.JLabel lbTotalCount;
    private javax.swing.JTextArea taCurrentFolder;
    private javax.swing.JTextField txtCurrentFile;
    // End of variables declaration//GEN-END:variables

}
